package com.tw.trips.ui;

import java.util.Date;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Service;

import com.tw.trips.domain.Alert;
import com.tw.trips.domain.Comment;
import com.tw.trips.domain.ItHelps;
import com.tw.trips.domain.Location;
import com.tw.trips.domain.Traveller;
import com.tw.trips.domain.Update;
import com.tw.trips.domain.WeatherUpdate;
import com.tw.trips.service.LocationService;
import com.tw.trips.service.TravellerService;
import com.tw.trips.service.WeatherAlertService;
import com.tw.trips.ui.mock.TravellerMock;
import com.vaadin.terminal.ExternalResource;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.Label;
import com.vaadin.ui.Link;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.VerticalSplitPanel;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.BaseTheme;

@Service
@Configurable(preConstruction = true)
public class MainPage extends VerticalLayout {

	public static final String IMG_URL = "http://my-trips.cloudfoundry.com/images/";
	Panel otherPanel;
	Panel links;
	Panel contents;
	Panel locationSearch;
	Panel alertPanel;
	HorizontalSplitPanel mainHorzSplitPanel;
	VerticalSplitPanel mainVertSplitPanel;
	HorizontalSplitPanel subHorzSplitPanel;
	Location currentLocation;
	Traveller currentTraveller;
	Window subwindow;

	@Autowired
	private LocationService locationService;

	@Autowired
	private TravellerService travellerService;

	@Autowired
	private WeatherAlertService weatherService;

	public MainPage() {
		super();
		// TODO Auto-generated constructor stub
	}

	public MainPage(Location location, Traveller traveller) {
		setSizeFull();

		currentTraveller = traveller;
		currentLocation = location;
		mainVertSplitPanel = new VerticalSplitPanel();
		mainVertSplitPanel.setSplitPosition(10);
		addComponent(mainVertSplitPanel);

		mainVertSplitPanel.addComponent(getHeader("My Trips",
				Alignment.TOP_CENTER));

		mainHorzSplitPanel = new HorizontalSplitPanel();
		mainHorzSplitPanel.setSplitPosition(20); // percent
		mainVertSplitPanel.addComponent(mainHorzSplitPanel);

		links = getLinksPanel();
		mainHorzSplitPanel.addComponent(links);

		subHorzSplitPanel = new HorizontalSplitPanel();
		subHorzSplitPanel.setSplitPosition(80);

		// Loads the Content Central Pannel for the Passed Fully Loaded Location
		// Object
		contents = getContentPane(location);

		subHorzSplitPanel.addComponent(contents);
		otherPanel = getOthersPanel();
		subHorzSplitPanel.addComponent(otherPanel);

		mainHorzSplitPanel.addComponent(subHorzSplitPanel);

	}

	private Panel getContentPane(Location location) {
		Panel panel = new Panel();
		panel.setCaption("Current Location Updates");
		panel.setHeight("100%");
		panel.setWidth("100%");
		VerticalLayout vert = new VerticalLayout();
		panel.addComponent(vert);

		if (location != null) {
			Label locationName = new Label(location.getName());
			vert.addComponent(locationName);
			vert.addComponent(includeAddUpdateButton(location));
			vert.addComponent(LineBreak.getLinkeBreak());
			for (Update update : location.getUpdates()) {
				vert.addComponent(includeMainUpdateHorzLayout(update));
				vert.addComponent(LineBreak.getLinkeBreak());
				vert.addComponent(includeAddCommentPane(update));
				for (Comment comment : update.getComments()) {
					vert.addComponent(includeCommentHorzLayout(comment));
				}
			}
		}

		return panel;
	}

	private HorizontalLayout includeMainUpdateHorzLayout(Update update) {
		HorizontalLayout mainUpdateHorzLayout = new HorizontalLayout();
		mainUpdateHorzLayout.setSpacing(true);
		/*Embedded updatedByPic = new Embedded("", new ThemeResource(
				"../runo/icons/32/user.png"));*/
		
		Embedded updatedByPic = new Embedded("", new ExternalResource(IMG_URL+update.getUpdatedBy().getEmailID()+".jpg"));
		updatedByPic.setHeight("40px");
		updatedByPic.setWidth("40px");
		Label updatedByLabel = new Label(update.getUpdatedBy().getName());
		Label updateTxt = new Label(update.getMessage());
		// Embedded itHelps = new Embedded("",new
		// ThemeResource("../runo/icons/32/arrow-up.png"));

		Button itHelpsBtn = new Button();
		itHelpsBtn.setData(update);
		itHelpsBtn.setIcon(new ThemeResource("../runo/icons/32/arrow-up.png"));
		itHelpsBtn.setStyleName(BaseTheme.BUTTON_LINK);
		// trips.setStyleName(Button.STYLE_LINK);
		itHelpsBtn.setDescription("It Helps You?");
		itHelpsBtn.addListener(new Button.ClickListener() {

			public void buttonClick(ClickEvent event) {
				// TODO : Increment it helps count
				Update updateLiked = (Update) event.getButton().getData();
				// updateLiked.getItHelps().add(itHelps);
				Location updatedLoc = locationService.addItHepsToUpdate(
						updateLiked, currentTraveller);
				contents = getContentPane(updatedLoc);
				subHorzSplitPanel.setFirstComponent(contents);

			}
		});

		Label itHelpsCount = new Label("" + update.getItHelps().size());

		mainUpdateHorzLayout.addComponent(updatedByPic);
		mainUpdateHorzLayout.setComponentAlignment(updatedByPic,
				Alignment.MIDDLE_CENTER);
		mainUpdateHorzLayout.addComponent(updatedByLabel);
		mainUpdateHorzLayout.setComponentAlignment(updatedByLabel,
				Alignment.MIDDLE_CENTER);
		mainUpdateHorzLayout.addComponent(updateTxt);
		mainUpdateHorzLayout.setComponentAlignment(updateTxt,
				Alignment.MIDDLE_CENTER);
		mainUpdateHorzLayout.addComponent(itHelpsBtn);
		mainUpdateHorzLayout.setComponentAlignment(itHelpsBtn,
				Alignment.MIDDLE_RIGHT);

		mainUpdateHorzLayout.addComponent(itHelpsCount);
		mainUpdateHorzLayout.setComponentAlignment(itHelpsCount,
				Alignment.BOTTOM_CENTER);
		return mainUpdateHorzLayout;
	}

	private HorizontalLayout includeCommentHorzLayout(Comment comment) {
		HorizontalLayout mainUpdateHorzLayout = new HorizontalLayout();
		mainUpdateHorzLayout.setSpacing(true);
		// mainUpdateHorzLayout.setWidth("500px");
		Embedded commentedByPic = new Embedded("", new ExternalResource(IMG_URL+comment.getCommentedBy().getEmailID()+".jpg"));
		commentedByPic.setHeight("40px");
		commentedByPic.setWidth("40px");
		Label commentedBy = new Label(comment.getCommentedBy().getName());
		Label commentTxt = new Label(comment.getMessage());

		// Embedded itHelps = new Embedded("",new
		// ThemeResource("../runo/icons/16/arrow-up.png"));

		Button itHelpsBtn = new Button();
		itHelpsBtn.setData(comment);
		itHelpsBtn.setIcon(new ThemeResource("../runo/icons/32/arrow-up.png"));
		itHelpsBtn.setStyleName(BaseTheme.BUTTON_LINK);
		// trips.setStyleName(Button.STYLE_LINK);
		itHelpsBtn.setDescription("You like it?");
		itHelpsBtn.addListener(new Button.ClickListener() {

			public void buttonClick(ClickEvent event) {
				// TODO : Increment it helps count
				Comment commentLiked = (Comment) event.getButton().getData();
				ItHelps itHelps = new ItHelps();
				// commentLiked.getItHelps().add(itHelps);
				Location updatedLoc = locationService.addItHepsToComment(
						commentLiked, currentTraveller);
				contents = getContentPane(updatedLoc);
				subHorzSplitPanel.setFirstComponent(contents);

			}
		});

		Label itHelpsCount = new Label("" + comment.getItHelps().size());

		mainUpdateHorzLayout.addComponent(commentedByPic);
		mainUpdateHorzLayout.setComponentAlignment(commentedByPic,
				Alignment.MIDDLE_CENTER);
		mainUpdateHorzLayout.addComponent(commentedBy);
		mainUpdateHorzLayout.setComponentAlignment(commentedBy,
				Alignment.MIDDLE_CENTER);
		mainUpdateHorzLayout.addComponent(commentTxt);
		mainUpdateHorzLayout.setComponentAlignment(commentTxt,
				Alignment.MIDDLE_CENTER);
		mainUpdateHorzLayout.addComponent(itHelpsBtn);
		mainUpdateHorzLayout.setComponentAlignment(itHelpsBtn,
				Alignment.MIDDLE_RIGHT);

		mainUpdateHorzLayout.addComponent(itHelpsCount);
		mainUpdateHorzLayout.setComponentAlignment(itHelpsCount,
				Alignment.BOTTOM_CENTER);

		return mainUpdateHorzLayout;
	}

	private Panel getOthersPanel() {
		Panel panel = new Panel();
		panel.setHeight("100%");
		panel.setWidth("100%");

		VerticalLayout vertLayout = new VerticalLayout();
		panel.addComponent(vertLayout);

		Label location = new Label("Chennai");
		vertLayout.addComponent(location);
		vertLayout.addComponent(LineBreak.getLinkeBreak());
		Map<String, WeatherUpdate> weatherUpdate = weatherService
				.getAlerts("Chennai");

		for (String index : weatherUpdate.keySet()) {
			WeatherUpdate weather = weatherUpdate.get(index);
			Label dayOfWeek = new Label(getDayOfWeek(index));
			String imageURL = "<img src=\"" + weather.getIcon() + "\"/>";
			Label icon = new Label(imageURL, Label.CONTENT_XHTML);
			Label high = new Label("High " + weather.getHighData());
			Label low = new Label("Low " + weather.getLowData());
			Label condition = new Label("Condition " + weather.getCondition());
			vertLayout.addComponent(dayOfWeek);
			vertLayout.addComponent(icon);
			vertLayout.addComponent(high);
			vertLayout.addComponent(low);
			vertLayout.addComponent(condition);
			vertLayout.addComponent(LineBreak.getLinkeBreak());

		}

		return panel;
	}

	private String getDayOfWeek(String index) {
		if ("0".equalsIgnoreCase(index)) {
			return "Today";
		} else if ("1".equalsIgnoreCase(index)) {
			return "Tomorrow";
		} else {
			return "Day After";
		}
	}

	private Panel getLinksPanel() {
		Panel panel = new Panel();
		panel.setHeight("100%");
		panel.setWidth("100%");
		VerticalLayout vertLayout = (VerticalLayout) panel.getContent();

		Button trips = new Button("Trips");
		trips.setStyleName(BaseTheme.BUTTON_LINK);
		trips.setDescription("Lists your trips!");
		trips.addListener(new Button.ClickListener() {

			public void buttonClick(ClickEvent event) {
				subHorzSplitPanel.removeComponent(contents);
				// currentTraveller = new TravellerMock().getTraveller();
				currentTraveller = travellerService
						.getTraveller(currentTraveller.getEmailID());
				TripsPanel trips = new TripsPanel(currentTraveller,
						subHorzSplitPanel);
				subHorzSplitPanel.setFirstComponent(trips);

			}
		});

		Button alerts = new Button("Alerts");
		alerts.setStyleName(BaseTheme.BUTTON_LINK);
		alerts.setDescription("Alerts for your Trip!");
		alerts.addListener(new Button.ClickListener() {

			public void buttonClick(ClickEvent event) {

				alertPanel = getAlertPanel();
				subHorzSplitPanel.setFirstComponent(alertPanel);

			}

			private Panel getAlertPanel() {
				Panel panel = new Panel();

				panel.setHeight("100%");
				panel.setWidth("100%");
				panel.setCaption("Alerts!");

				VerticalLayout vertLayout = new VerticalLayout();

				Traveller traveller = currentTraveller;

				if (traveller.getAlerts() != null) {
					for (Alert alert : traveller.getAlerts()) {
						HorizontalLayout horzLayout = new HorizontalLayout();

						// Label trainName = new
						// Label(LineBreak.SAMPLE_ALERT,Label.CONTENT_XHTML);
						Label trainName = new Label(alert.getHtml(),
								Label.CONTENT_XHTML);

						vertLayout.addComponent(trainName);
						vertLayout.addComponent(LineBreak.getLinkeBreak());
					}
				}

				panel.addComponent(vertLayout);
				return panel;

			}
		});

		Button locations = new Button("Locations");
		locations.setStyleName(BaseTheme.BUTTON_LINK);
		locations.setDescription("Your Locations!");

		locations.addListener(new Button.ClickListener() {
			TextField locationName;

			public void buttonClick(ClickEvent event) {
				Panel locationSearch = new Panel();

				locationSearch.setHeight("100%");
				locationSearch.setWidth("100%");
				locationSearch.setCaption("Updates For?");

				VerticalLayout vertLayout = new VerticalLayout();
				locationName = new TextField("Search For:");
				vertLayout.addComponent(locationName);
				vertLayout.addComponent(includeSearchButton());
				locationSearch.addComponent(vertLayout);
				subHorzSplitPanel.setFirstComponent(locationSearch);

			}

			private Component includeSearchButton() {
				// Button w/ text and tooltip
				Button addCommentButton = new Button("Search");

				addCommentButton.setDescription("Search");
				addCommentButton.addListener(new ClickListener() {

					public void buttonClick(ClickEvent event) {

						String location = (String) locationName.getValue();
						// Form location object
						contents = getContentPane(locationService
								.getLocation(location));
						subHorzSplitPanel.setFirstComponent(contents);

					}
				});

				return addCommentButton;
			}
		});

		Button updates = new Button("Updates");
		updates.setStyleName(BaseTheme.BUTTON_LINK);
		updates.setDescription("Your Updates!");
		updates.addListener(new Button.ClickListener() {
			// TODO Content Pannel currenlty supports only location, need to add
			// a flag to indicate LOcation updates OR
			// Travelller updates.
			public void buttonClick(ClickEvent event) {

			}
		});

		Button home = new Button("Home");
		home.setStyleName(BaseTheme.BUTTON_LINK);
		home.setDescription("Home!");
		home.addListener(new Button.ClickListener() {

			public void buttonClick(ClickEvent event) {
				contents = getContentPane(locationService
						.getLocation(currentLocation.getName()));

				subHorzSplitPanel.setFirstComponent(contents);
			}
		});

//		Link twitterLink = new Link("Tweets",new ExternalResource("http://localhost:8080/My-Trips/tweetfeed.html"));
		Link twitterLink = new Link("Tweets",new ExternalResource("http://my-trips.cloudfoundry.com/tweetfeed.html"));
		twitterLink.setTargetName("_blank");
		twitterLink.setTargetBorder(Link.TARGET_BORDER_NONE);
		twitterLink.setDescription("Tweets");

		vertLayout.addComponent(home);
		vertLayout.setComponentAlignment(home, Alignment.MIDDLE_LEFT);
		vertLayout.addComponent(trips);
		vertLayout.setComponentAlignment(trips, Alignment.MIDDLE_LEFT);
		vertLayout.addComponent(alerts);
		vertLayout.setComponentAlignment(alerts, Alignment.MIDDLE_LEFT);
		vertLayout.addComponent(locations);
		vertLayout.setComponentAlignment(locations, Alignment.MIDDLE_LEFT);

		vertLayout.addComponent(twitterLink);
		vertLayout.setComponentAlignment(twitterLink, Alignment.MIDDLE_LEFT);


		return panel;

	}

	private Panel getHeader(String content, Alignment alignment) {
		Panel panel = new Panel();
		VerticalLayout vertLayout = (VerticalLayout) panel.getContent();
		Label label = new Label(content);
		panel.addComponent(label);

		vertLayout.addComponent(label);
		vertLayout.setComponentAlignment(label, alignment);
		return panel;
	}

	private Component includeAddCommentPane(Update update) {
		// Button w/ text and tooltip
		Button addCommentButton = new Button("Add Comment");
		addCommentButton.setStyleName(BaseTheme.BUTTON_LINK);
		addCommentButton.setDescription("To add comment");
		addCommentButton.setData(update);
		addCommentButton.addListener(new ClickListener() {

			public void buttonClick(ClickEvent event) {
				handleAddComment(event);

			}
		}); // react to clicks

		return addCommentButton;
	}

	public void handleAddComment(ClickEvent event) {
		// Create the window...
		subwindow = new Window("Your say?");
		// ...and make it modal
		subwindow.setModal(true);
		subwindow.setHeight("50px");
		subwindow.setWidth("400px");
		subwindow.setData(((Button) event.getSource()).getData());
		// Configure the windws layout; by default a VerticalLayout
		VerticalLayout layout = (VerticalLayout) subwindow.getContent();
		layout.setMargin(true);
		layout.setSpacing(true);

		TextArea editor = new TextArea(null, "");
		editor.setRows(2);
		editor.setColumns(28);
		layout.addComponent(editor);

		Button addCommentButton = new Button("Add Comment",
				new Button.ClickListener() {
			// inline click-listener
			public void buttonClick(ClickEvent event) {
				Update update = (Update) subwindow.getData();
				VerticalLayout layout = (VerticalLayout) subwindow
						.getContent();
				TextArea txtArea = (TextArea) layout.getComponent(0);
				String commentTxt = (String) txtArea.getValue();
				Date createdOn = new Date();
				// Comment comment = new Comment();
				// comment.setMessage(commentTxt);
				// //TODO
				// comment.setCommentedBy(new Traveller());
				// comment.setCreatedOn(createdOn);

				// update.getComments().add(comment);
				Location updatedLoc = locationService
						.putCommentForUpdate(update, createdOn,
								currentTraveller, commentTxt);
				contents = getContentPane(updatedLoc);

				subHorzSplitPanel.setFirstComponent(contents);

				(subwindow.getParent()).removeWindow(subwindow);
			}
		});
		// The components added to the window are actually added to the window's
		// layout; you can use either. Alignments are set using the layout
		layout.addComponent(addCommentButton);
		layout.setComponentAlignment(addCommentButton, Alignment.TOP_RIGHT);
		getWindow().addWindow(subwindow);

	}

	private Component includeAddUpdateButton(Location location) {
		// Button w/ text and tooltip
		Button addActivityButton = new Button("Add Update");
		addActivityButton.setStyleName(BaseTheme.BUTTON_LINK);
		addActivityButton.setDescription("To add an update!");
		addActivityButton.setData(location);
		addActivityButton.addListener(new ClickListener() {

			public void buttonClick(ClickEvent event) {
				// Create the window...
				subwindow = new Window("Your say?");
				// ...and make it modal
				subwindow.setModal(true);
				subwindow.setHeight("50px");
				subwindow.setWidth("400px");
				subwindow.setData(((Button) event.getSource()).getData());
				// Configure the windws layout; by default a VerticalLayout
				VerticalLayout layout = (VerticalLayout) subwindow.getContent();
				layout.setMargin(true);
				layout.setSpacing(true);

				TextArea editor = new TextArea(null, "");
				editor.setRows(2);
				editor.setColumns(28);
				layout.addComponent(editor);

				Button addCommentButton = new Button("Add Update",
						new Button.ClickListener() {
					// inline click-listener
					public void buttonClick(ClickEvent event) {
						Location location = (Location) subwindow
								.getData();
						VerticalLayout layout = (VerticalLayout) subwindow
								.getContent();
						TextArea txtArea = (TextArea) layout
								.getComponent(0);
						String updateTxt = (String) txtArea.getValue();

						Update update = new Update();
						update.setMessage(updateTxt);
						update.setCreatedOn(new Date());
						// update.setUpdatedBy(currentTraveller);

						// location.getUpdates().add(update);
						Location updatedLoc = locationService
								.putUpdateForLocation(location,
										currentTraveller, update);
						contents = getContentPane(updatedLoc);

						subHorzSplitPanel.setFirstComponent(contents);

						(subwindow.getParent()).removeWindow(subwindow);
					}
				});
				// The components added to the window are actually added to the
				// window's
				// layout; you can use either. Alignments are set using the
				// layout
				layout.addComponent(addCommentButton);
				layout.setComponentAlignment(addCommentButton,
						Alignment.TOP_RIGHT);
				getWindow().addWindow(subwindow);
			}
		}); // react to clicks

		return addActivityButton;
	}
}
